grammar WebConverter;
options{
	output=template;
	rewrite=true;
	language=CSharp3;
}
/*
This grammar is for turning Watler's parser as specified on his web page
into a valid Antlr grammar. Paste all the relevant lines of his BNF
into a text file, and push it through this rewriting grammar. Out comes a mostly
valid Antlr grammar.
*/

firstParsingRule
	:	(rule | Comment | blankLine)*
	;

//don't allow comments inside rules, to keep it simple
rule
	:	start=startOfRule lines+=alternativeLine+
		-> template(start={$start.text}, lines={$lines}) "<start><lines; separator=\"\t|\t\"><\t>;<\n>"
	;

startOfRule
	:	ruleName Colon WhiteSpace* NewLine
		-> template(ruleName={$ruleName.text.Substring(0, 1).ToLower() + $ruleName.text.Substring(1)})"<ruleName><\n\t>:<\t>"
	;

alternativeLine
	:	WhiteSpace+ el+=alternativeElement (WhiteSpace+ el+=alternativeElement)* WhiteSpace? NewLine
		-> template(arg={$el}) "<arg; separator=\" \"><\n>"
	;

alternativeElement
	:	DontTranslate
		->template(retval={$text})"<retval>"
	|	(Punctuation|Colon)+
		-> template(retval={"'" + $text + "'"})"<retval>"
	|	surroundWithQuotes
		-> template(retval={"'" + $text + "'"})"<retval>"
	|	ruleName 
		-> template(retval={$text.Substring(0, 1).ToLower() + $text.Substring(1)})"<retval>"
	;

blankLine
	:	WhiteSpace* NewLine
		-> template() "<\n>"
	;
	
ruleName
	:	Import
		-> template()"ImportRule"
	|	Catch
		-> template()"CatchRule"
	|	CapitalizedWord
		-> template(retval={$text})"<retval>"
	;

surroundWithQuotes
	:	LinkageType
	|	LowercaseWord
	;
	
LinkageType
	:	'C' | 'C++' | 'D' | 'Windows' | 'Pascal' | 'System' 
	;

//these are keywords in Antlr, rename them
Import
	:	'Import'
	;

Catch
	:	'Catch'
	;

DontTranslate
	:	'Identifier'
	|	'StringLiteral'
	|	'IntegerLiteral'
	|	'FloatLiteral'
	|	'CharacterLiteral'
	;

Punctuation
	:	'!' | '$' | '%' | '^' | '&' | '*' | '(' | ')' | '-' | '+' | '=' | '{' | '}' | '[' | ']' | '|' | ';' | '<' | '>' | ',' | '.' | '?' | '/' | '~'
	;
	
Colon
	:	':'
	;
	
CapitalizedWord
	:	UppercaseLetter (Letter | Number)*
	;

LowercaseWord
	:	LowercaseLetter (Letter | Number)*
	;
	
NewLine	:	'\n' | '\r' | '\r\n'
	;
	
WhiteSpace
	:	' ' | '\t'
	;

Comment	:	'//' (~FragmentNewLine)* NewLine
	;
	
fragment
FragmentNewLine
	:	'\n' | '\r'
	;
	
fragment
Number
	:	'0'..'9'
	;

fragment
Letter
	:	UppercaseLetter | LowercaseLetter
	;
	
fragment
UppercaseLetter
	:	'A'..'Z';

fragment
LowercaseLetter
	:	'a'..'z';
